﻿using System;
using System.IO;

namespace Bioinformatics.Types
{
    public class PsomlConfiguration
    {
        public float CurrentCoefficient { get; set; }

        /// <summary>
        /// Maximum number of iterations the swarm undergoes.
        /// </summary>
        public int GenerationMax { get; set; }

        public float GlobalCoefficient { get; set; }
        public string InputFile { get; set; }

        /// <summary>
        /// Maximum change in branch length per iteration.
        /// </summary>
        public float LengthDeltaMax { get; set; }

        /// <summary>
        /// Minimum change in branch length per iteration.
        /// </summary>
        public float LengthDeltaMin { get; set; }

        /// <summary>
        /// Maximum branch length.
        /// </summary>
        public float LengthMax { get; set; }

        /// <summary>
        /// Minimum branch length.
        /// </summary>
        public float LengthMin { get; set; }

        public float LocalBestCoefficient { get; set; }

        public float LocalCoefficient { get; set; }

        /// <summary>
        /// Size of social group per swarm.
        /// </summary>
        public int NeighborhoodSize { get; set; }

        public float NeighbourhoodCoefficient { get; set; }

        /// <summary>
        /// Maximum random component per iteration.
        /// </summary>
        public float RandomVectorMax { get; set; }

        /// <summary>
        /// Minimum random component per iteration.
        /// </summary>
        public float RandomVectorMin { get; set; }

        /// <summary>
        /// Size of the optimizing swarm.
        /// </summary>
        public int SwarmSize { get; set; }

        public void ExportToCafFile(string path)
        {
            //open the stream writer to write to
            var streamWriter = new StreamWriter(path, false);
            //write each property to file
            streamWriter.WriteLine("--inputfile=" + InputFile);
            streamWriter.WriteLine("--maxgenerations=" + GenerationMax);
            streamWriter.WriteLine("--currentcoefficient=" + CurrentCoefficient);
            streamWriter.WriteLine("--globalcoefficient=" + GlobalCoefficient);
            streamWriter.WriteLine("--neighborhoodcoefficient=" + NeighbourhoodCoefficient);
            streamWriter.WriteLine("--localbestcoefficient=" + LocalCoefficient);
            streamWriter.WriteLine("--swarmsize=" + SwarmSize);
            streamWriter.WriteLine("--lengthdeltamax=" + LengthDeltaMax);
            streamWriter.WriteLine("--lengthdeltamin=" + LengthDeltaMin);
            streamWriter.WriteLine("--lengthmax=" + LengthMax);
            streamWriter.WriteLine("--lengthmin=" + LengthMin);
            streamWriter.WriteLine("--neighbourhoodsize=" + NeighborhoodSize);
            streamWriter.WriteLine("--randomvectormax=" + RandomVectorMax);
            streamWriter.WriteLine("--randomvectormin=" + RandomVectorMin);
            //close the stream writer
            streamWriter.Close();
        }

        public static PsomlConfiguration ImportFromFile(string path)
        {
            try
            {
                var psomlConfiguration = new PsomlConfiguration();
                //open stream reader
                var streamReader = new StreamReader(path);
                //get each line in the config file
                string[] configLines = streamReader.ReadToEnd().Split('\n');
                //iterate through each line
                for (int i = 0; i < configLines.Length; i++)
                {
                    if (configLines[i].StartsWith("--inputfile="))
                        psomlConfiguration.InputFile = configLines[i].Split('=')[1];
                    else if (configLines[i].StartsWith("--maxgenerations="))
                        psomlConfiguration.GenerationMax = int.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--currentcoefficient="))
                        psomlConfiguration.CurrentCoefficient = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--globalcoefficient="))
                        psomlConfiguration.GlobalCoefficient = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--neighborhoodcoefficient="))
                        psomlConfiguration.NeighbourhoodCoefficient = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--localbestcoefficient="))
                        psomlConfiguration.LocalCoefficient = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--swarmsize="))
                        psomlConfiguration.SwarmSize = int.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--lengthdeltamax="))
                        psomlConfiguration.LengthDeltaMax = int.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--lengthdeltamin="))
                        psomlConfiguration.LengthDeltaMin = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--lengthmax="))
                        psomlConfiguration.LengthMax = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--lengthmin="))
                        psomlConfiguration.LengthDeltaMin = float.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--neighbourhoodsize="))
                        psomlConfiguration.NeighborhoodSize = int.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--randomvectormax="))
                        psomlConfiguration.RandomVectorMax = int.Parse(configLines[i].Split('=')[1]);
                    else if (configLines[i].StartsWith("--randomvectormin="))
                        psomlConfiguration.RandomVectorMin = int.Parse(configLines[i].Split('=')[1]);
                }

                return psomlConfiguration;
            }
            catch (Exception)
            {
                return new PsomlConfiguration();
            }
        }
    }
}